package com.yxc.translationdemo.entity;

import cn.hutool.core.lang.Singleton;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import com.yxc.translationdemo.annotation.Translation;
import com.yxc.translationdemo.transcode.TranslationData;
import com.yxc.translationdemo.utils.SpringContextHolder;
import lombok.SneakyThrows;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;

import java.lang.reflect.Field;

/**
 * 可以转义的
 *
 * @author: YXC
 * @time: 2022/12/5 19:26
 **/
public interface Translated {

    @SneakyThrows
    default void translate() {
        Class<? extends Translated> clazz = this.getClass();
        for (Field field : clazz.getDeclaredFields()) {
            Translation translation = field.getAnnotation(Translation.class);
            if (translation == null) {
                continue;
            }
            // 获取字段名
            String transFieldName = translation.fieldName();
            // 验证字段是否存在
            if (!ReflectUtil.hasField(clazz, transFieldName)) {
                throw new NoSuchFieldException(StrUtil.format("字段{}不存在", transFieldName));
            }
            // 判断字段是否有值
            Object currentFieldValue = ReflectUtil.getFieldValue(this, field);
            if (ObjectUtil.isEmpty(currentFieldValue)) {
                continue;
            }
            if (!translation.isCover()) {
                continue;
            }
            // 验证dataSource有效性
            Class<?> transClass;
            if (translation.dataSourceClassName() != null && !translation.dataSourceClassName().equals("")) {
                transClass = Class.forName(translation.dataSourceClassName());
            } else {
                transClass = translation.dataSource();
            }
            if (!TranslationData.class.isAssignableFrom(transClass)) {
                throw new IllegalAccessException(StrUtil.format("dataSource字段必须实现TranslationData接口({})", field.getName()));
            }
            // 获取dataSource
            TranslationData translationData = null;
            // 1. 判断是否是emun，直接调用
            if (transClass.isEnum()) {
                Object[] enumConstants = transClass.getEnumConstants();
                if (enumConstants.length > 0) {
                    translationData = (TranslationData) enumConstants[0];
                } else {
                    throw new IllegalAccessException("枚举类无常量，请检查");
                }
            }
            // 2. 尝试从spring中获取
            ApplicationContext applicationContext = SpringContextHolder.getApplicationContext();
            if (translationData == null && applicationContext != null) {
                try {
                    translationData = (TranslationData) applicationContext.getBean(transClass);
                } catch (BeansException ignored) {
                }
            }
            if (translationData == null) {
                // 3. 从hutool单例池当中获取
                translationData = (TranslationData) Singleton.get(transClass);
                if (translationData == null) {
                    throw new IllegalAccessException(StrUtil.format("获取数据源失败，请检查({})", field.getName()));
                }
            }
            // 获取值
            String transResult = translationData.get(currentFieldValue, field);
            // 字段赋值
            ReflectUtil.setFieldValue(this, transFieldName, transResult);
        }
    }
}
